package blazingbubble.gui;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLCapabilities;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.apache.log4j.Logger;

import blazingbubble.config.Config;
import blazingbubble.game.Game;
import blazingbubble.game.ILobbyGameEventListener;
import blazingbubble.game.command.GameCommandFactory;
import blazingbubble.graphics.game.InGame;
import blazingbubble.graphics.lobby.IGameListUpdateListener;
import blazingbubble.gui.panels.BrowseGamesPanel;
import blazingbubble.gui.panels.GameLobbyPanel;
import blazingbubble.gui.panels.HostGameDefaultOptionsPanel;
import blazingbubble.gui.panels.JoinIPPanel;
import blazingbubble.gui.panels.MainMenuPanel;
import blazingbubble.lobby.command.LobbyCommandFactory;
import blazingbubble.network.game.strategy.IJoinGameResponseResultListener;
import blazingbubble.network.game.strategy.IStartGameListener;
import blazingbubble.network.lobby.strategy.ILoginResponseResultListener;


public class MainWindow extends JFrame implements ISwitchable, ILoginResponseResultListener, IStartGameListener, IJoinGameResponseResultListener{
	private static final long serialVersionUID = -3286943885307599947L;
	
	private static Logger logger = Logger.getLogger(MainWindow.class);

	private GLCanvas canvas = null;
	
	private MainMenuPanel mainMenuPanel = null;
	
	private GameCommandFactory gameCommandFactory = null;
	private LobbyCommandFactory lobbyCommandFactory = null;
	
	private boolean loggedIn = false;
	private boolean waitingForLoginResponse = false;
	
	private Game game = null;
	//private InGame inGame = null;

	public MainWindow(GameCommandFactory gameCommandFactory, LobbyCommandFactory lobbyCommandFactory,
			blazingbubble.game.Game game, ILobbyGameEventListener lobbyGameEventListener, Integer frameBreak){
		this.gameCommandFactory = gameCommandFactory;
		this.lobbyCommandFactory = lobbyCommandFactory;
		this.game = game;
		
		GLCapabilities glcaps = new GLCapabilities();
		canvas = new GLCanvas(glcaps);
		getContentPane().add(canvas);
	//	this.inGame = new InGame(getContentPane(), gameCommandFactory, game, frameBreak);
		mainMenuPanel = new MainMenuPanel(this);
		//((BrowseGamesPanel)PanelRegistry.getInstance().lookUpPanel(BrowseGamesPanel.PANEL_NAME)).setJoinGameListener(this.game.getGameStartup());
		((BrowseGamesPanel)PanelRegistry.getInstance().lookUpPanel(BrowseGamesPanel.PANEL_NAME)).setLobbyGameEventListener(lobbyGameEventListener);
		((HostGameDefaultOptionsPanel)PanelRegistry.getInstance().lookUpPanel(HostGameDefaultOptionsPanel.PANEL_NAME)).setLobbyGameEventListener(lobbyGameEventListener);
		((JoinIPPanel)PanelRegistry.getInstance().lookUpPanel(JoinIPPanel.PANEL_NAME)).setLobbyGameEventListener(lobbyGameEventListener);
	}

	public void startUp(Config config){
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				shutdown();
			}
			});
		
		this.setResizable(false);
		this.setTitle("Crayon Bubble");
		this.setUndecorated(false);
		this.setSize(350, 450);
		this.setLocationRelativeTo(null);
		
		((BrowseGamesPanel)PanelRegistry.getInstance().lookUpPanel(BrowseGamesPanel.PANEL_NAME)).setJoinGameListener(
				((GameLobbyPanel)PanelRegistry.getInstance().lookUpPanel(GameLobbyPanel.PANEL_NAME)));

		this.add(mainMenuPanel);
	}

	@Override
	public void switchPanel(JPanel newPanel){
		this.getContentPane().removeAll();
		this.getContentPane().add(newPanel);
		((JPanel)this.getContentPane()).updateUI();
	}

	@Override
	public void shutdown() {
		this.dispose();		
	}

	@Override
	public void switchSize(int width, int height) {
		this.setSize(width, height);
		this.setLocationRelativeTo(null);
		this.repaint();
	}
	
	public void update() {
		canvas.display();
	}
	
	public IGameListUpdateListener getGameListUpdateListener(){
		return (IGameListUpdateListener)PanelRegistry.getInstance().lookUpPanel(BrowseGamesPanel.PANEL_NAME);
	}
	
	@Override
	public void loginSuccessfull() {
		loggedIn = true;
		waitingForLoginResponse = false;
	}

	@Override
	public void loginFailed(String reason) {
		this.notify();
		loggedIn = false;
		waitingForLoginResponse = false;
		//TODO: logger message, error
	}

	@Override
	public void gameStarted() {
		switchSize(800, 600);
		//inGame.activate();
	}

	@Override
	public GameCommandFactory getGameCommandFactory() {
		return gameCommandFactory;
	}

	@Override
	public LobbyCommandFactory getLobbyCommandFactory() {
		return lobbyCommandFactory;
	}

	@Override
	public boolean isLoggedIn() {
		return loggedIn;
	}

	@Override
	public boolean isWaitingForLoginResponse() {
		return waitingForLoginResponse;		
	}
	
	@Override
	public void waitForLogin(){
		waitingForLoginResponse = true;
	}
	
	@Override
	public void joinFailed(String reason) {
		// TODO: handle error somehow
		logger.error(reason);		
	}

	@Override
	public void joinSuccessful() {
		switchSize(500, 500);
		switchPanel(PanelRegistry.getInstance().lookUpPanel(GameLobbyPanel.PANEL_NAME));		
	}

	@Override
	public Game getGame() {
		return game;
	}
}
